<template>
    <el-container>
        <vHeadSpace />
        <el-container>
            <vAsideSpace />
            <el-container>
                <el-main class="mapedit-main">
                    <div class="map-left-content">
                        <!-- 主内容-上部分  -->
                        <div class="left_head">
                            <div class="content-header">
                                <!-- InstanceBeginEditable name="PageTitleRegion1" -->
                                <div class="pagename-list">
                                    <div class="pagename-header">
                                        <div class="context">
                                            <!-- 拓谱图选择框 -->
                                            <el-select
                                                    v-if="this.viewFlag"
                                                    size="small"
                                                    v-model="tuopuOptionsCurrent"
                                                    clearable
                                                    placeholder="选择切换拓扑图"
                                                    @change="selectChanged($event)"
                                            >
                                                <el-option
                                                        v-for="item in tuopuOptions"
                                                        :key="item.sysmapid"
                                                        :label="item.name"
                                                        :value="item">
                                                </el-option>
                                            </el-select>
                                            <el-select
                                                v-else
                                                size="small"
                                                v-model="businessWorkCurrent"
                                                clearable
                                                placeholder="选择切换业务"
                                                @change="selectChangeBusiness($event)"
                                            >
                                              <el-option
                                                  v-for="item in businessWork"
                                                  :key="item.workId"
                                                  :label="item.workName"
                                                  :value="item">
                                              </el-option>
                                            </el-select>
                                            <!-- 视图切换部分 -->
                                            <el-radio-group v-model="radioViewChoose" @change="viewSwitch">
                                                <el-radio :label="1">运行视图</el-radio>
                                                <el-radio :label="2">告警视图</el-radio>
                                                <el-radio :label="3">业务视图</el-radio>
                                            </el-radio-group>
                                            <button style="float:right;border: 0; margin-top: 8px" @click="toggleFullscreen">全屏</button>
                                        </div>
                                        <div class="unbutton"></div>
                                        <div style="float:right">

                                        </div>
                                    </div>
                                </div>

                                <div id="topo-backLast" style="float:right;font-size:14px;display: none;margin: 2px 10px;">
                                    <a onclick="Topo_backLast()" href="#">&lt;&lt;返回上一个拓扑图</a>
                                </div>
                            </div>
                        </div>
                        <!-- 主内容-下部分  -->
                        <div id="mapBody" class="map_body">
                            <button v-if="this.fullscreen == true" class="exitScreen" @click="toggleFullscreen">退出全屏</button>
                            <canvas
                                    id="canvas"
                                    style="border:1px solid #DFE4EA;float: left"
                                    :class="isGridShow?'mapCanvas-content':'noGrid'"
                            ></canvas>
                            <!-- 节点告警信息 -->
                            <div class="node-warning-dialog" v-show="nodeWarningDialogVisable">
                                <span>当前设备：{{dialogTitle}}</span>
                                <el-divider class="node-warning-divider"></el-divider>
                                <div v-show="alertInformation.alert_count==0?false:true">
                                    <span style="font-weight: bold">当前主机未处理告警共{{alertInformation.alert_count}}条，其中：</span><br>
                                    <span>未分类：{{alertInformation.undefine}}条</span><br>
                                    <span>信息类：{{alertInformation.infor}}条</span><br>
                                    <span>警告：{{alertInformation.alert}}条</span><br>
                                    <span>一般严重：{{alertInformation.yibanyanzhong}}条</span><br>
                                    <span>严重：{{alertInformation.yanzhong}}条</span><br>
                                    <span>灾难：{{alertInformation.zainan}}条</span>
                                </div>
                                <div v-show="alertInformation.alert_count==0?true:false">
                                    <span>无</span>
                                </div>
                            </div>

                            <!--  单设备视图信息弹窗  -->
                            <el-drawer
                                    title="单设备详情"
                                    :visible.sync="singleView"
                                    :with-header="false"
                                    size="20%"
                                    >
                                <div class="content-devices">
                                    <div class="base-infor">
                                        <span class="single-title">关联设备详情：</span>
                                        <el-button v-if="hostAboutInformation.status == '正常'" @click="monitorDetail" type="primary" size="mini" style="position: relative;float: right;margin-bottom: 4px">
                                            详情
                                        </el-button>
                                        <table border="1" frame="hsides" >
                                            <tr style="font-weight: bold;width: 40%"><td style="width: 40%">监控项</td><td>数值</td></tr>
                                            <tr><td>设备名称</td><td>{{hostAboutInformation.host}}</td></tr>
                                            <tr><td>设备接口</td><td>{{hostAboutInformation.ip}}:{{hostAboutInformation.port}}</td></tr>
                                            <tr><td>监控状态</td><td>{{hostAboutInformation.status}}</td></tr>
                                            <tr><td>CPU利用率</td><td>{{hostAboutInformation.cpu_utilization}}%</td></tr>
                                            <tr><td>磁盘利用率</td><td>{{hostAboutInformation.DiskUtilization}}%</td></tr>
                                            <tr><td>内存利用率</td><td>{{hostAboutInformation.memery_utilization}}%</td></tr>
                                        </table>
                                    </div>
                                    <!--运行视图中的告警信息显示隐藏-->
                                    <!--                                <div style="width: 100%;height: 30%;padding:10px 20px">-->
                                    <!--                                    <span class="single-title">未处理告警详情：</span>-->
                                    <!--                                    <el-button v-if="alertInformation.alert_count != 0" @click="unhandleAlertDetail" type="primary" size="mini" style="position: relative;float: right;margin-bottom: 4px">-->
                                    <!--                                      详情-->
                                    <!--                                    </el-button>-->
                                    <!--                                    <table border="1" frame="hsides" style="width: 100%;text-align: center">-->
                                    <!--                                        <tr style="font-weight: bold;width: 40%"><td>严重性等级</td><td>条数</td></tr>-->
                                    <!--                                        <tr><td style="width: 40%">未分类</td><td>{{alertInformation.undefine}}</td></tr>-->
                                    <!--                                        <tr><td>信息类</td><td>{{alertInformation.infor}}</td></tr>-->
                                    <!--                                        <tr><td>警告</td><td>{{alertInformation.alert}}</td></tr>-->
                                    <!--                                        <tr><td>一般严重</td><td>{{alertInformation.yibanyanzhong}}</td></tr>-->
                                    <!--                                        <tr><td>严重</td><td>{{alertInformation.yanzhong}}</td></tr>-->
                                    <!--                                        <tr><td>灾难</td><td>{{alertInformation.zainan}}</td></tr>-->
                                    <!--                                        <tr><td>总计</td><td>{{alertInformation.alert_count}}</td></tr>-->
                                    <!--                                    </table>-->
                                    <!--                                </div>-->
                                    <div class="bussness" >
                                        <span class="single-title">业务详情：</span>
                                        <table v-if="this.businessInformation == ''" border="1" frame="hsides" >
                                            <tr style="font-weight: bold;width: 40%">暂无业务</tr>
                                        </table>
                                        <table v-else border="1" frame="hsides">
                                            <tr style="font-weight: bold;width: 40%">
                                                <td style="width: 40%">业务ID</td>
                                                <td>业务名称</td>
                                            </tr>
                                            <tr v-for="(item,index) in this.businessInformation" :key="index">
                                                <td>{{item.business_id}}</td>
                                                <td>{{item.business_name}}</td>
                                            </tr>
                                        </table>
                                    </div>
                                    <div class="operator" >
                                        <el-button size="small" type="danger" @click="singleView=!singleView">关 闭</el-button>
                                    </div>
                                </div>
                            </el-drawer>
                        </div>
                    </div>
                </el-main>
                <vFootSpace />
            </el-container>
        </el-container>
    </el-container>
</template>

<style scoped>
    .content-devices{
        position: relative;
        height: 100%;
    }

    .content-devices>.base-infor {
        height: 30%;
        padding:10px 20px
    }

    .content-devices>.bussness {
        height: 30%;
        padding:10px 20px;
        margin-top: 20px
    }

    .content-devices>.operator {
        height: 8%;
        padding: 20px;
        position: absolute;
        bottom: 10px;
        left: 0;
    }

    .content-devices table {
        width: 100%;
        text-align: center;
        margin-top: 10px
    }

    .mapCanvas-content {
        background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.1) 2%, rgba(0, 0, 0, 0) 2%), linear-gradient(360deg, rgba(50, 0, 0, 0.1) 2%, rgba(0, 0, 0, 0) 2%);
        background-size: 26px 26px;
        background-repeat: repeat;
        background-position: center center;
    }

    .mapedit-main{
        height: 92vh;
        width: 100%;
        margin-top: 56px;
        padding:10px;
    }
    .map-left-content {
        height: 97%;
        overflow-x:hidden
    }

    /*<!-- 主内容-上部分  -->*/
    .left_head{
        width: 100%;
    }
    /*<!-- 主内容-下部分  -->*/
    .map_body {
        /*display: flex;*/
        position: relative;
        background-color: white;
        width: 100%;
        height: 94%;
    }

    /*<!-- 主内容-下部分-左边拓扑图内容  -->*/
    .map_body_left {
        background-color: white;
        width: 100%;
        height: 100%;
    }
    .el-radio-group {
        position: fixed;
        left: 50%;
        margin-top: 12px;
    }
    .exitScreen {
        width: 6rem;
        height: 2rem;
        position: absolute;
        top: 1rem;
        left: 84rem;
        border: 0;
    }

    .node-warning-dialog{
        position: absolute;
        top: 0;
        left: 0;
        /*background-color: lightgray;*/
        background-color: #FFE4FC;
        /*height: 100%;*/
        width: 14%;
        border:1px solid #FFFFFF;
        z-index: 10;
        font-size: 12px;
    }
    .node-warning-divider{
        margin-top: 2px;
        margin-bottom: 2px;
    }

    /*单设备视图*/
    .single-host-run-warning{
        position: absolute;
        right: 10px;
        background-color: #F0F2F5;
        width: 14%;
        /*height: 82vh;*/
        z-index: 10;
    }

    .node-warning-divider-subtitle{
        font-weight: bolder
    }
    .node-warning-divider-contentkey{
        margin-left: 10px;
    }
    .node-warning-divider-contentvalue{
        color: #0d47a1;
        margin-left: 5px
    }
    .single-title {
       font-size: 18px;
    }

</style>
<style>
    .tree-dialog-settings {
        background-color: #F0F2F5;
        height: 60%;
        width: 30%;
    }
    .el-dialog__body {
        padding-top: 0px;
    }
    .el-checkbox:last-of-type {
        margin-right: 8px;
        margin-bottom: 0px;
    }
    .el-tabs__item{
        padding-left: 20px !important;
    }
</style>

<script>
    import axios from 'axios'
    import screenfull from 'screenfull'
    import {topoImgSrc} from "../../../public/js/topoImgSrc.js"

    export default {
        name: "TopoViewShow",
        data() {
            return {
                radioViewChoose: 1,
                canvas: {},
                stage: {}, //舞台
                scene: {}, //场景
                engineRoomDetails: {},
                isGridShow: true,
                radioMode: 'drag',
                hostAboutInformation: {
                    host_id: '',
                    host: '/',
                    ip: '/',
                    port: '/',
                    status: '/',
                    type: '1',
                    memery_utilization: '/',
                    DiskUtilization: '/',
                    cpu_utilization: '/',
                },
                canvasWidth: document.body.clientWidth * 0.9,
                canvasHeight: document.body.clientHeight * 0.834,
                dialogEngineChooseVisible: false,
                filterText: '',
                fullscreen: false,
                activeName: 'first',
                showNumber: 1,
                tuopuOptionsCurrent: '无可展示拓扑图',
                tuopuOptions: [],
                timerWarningList: [],
                topoImgSrc: topoImgSrc,
                dialogTitle: '无设备',
                nodeWarningDialogVisable: false,
                singleView: false,// 单设备视图
                elementInf: null,
                alertInformation: {
                    "hostid": "",
                    "alert_count": 0,
                    "undefine": 0,
                    "infor": 0,
                    "alert": 0,
                    "yibanyanzhong": 0,
                    "yanzhong": 0,
                    "zainan": 0
                },
                alertInformationlist: [],
                viewFlag: true,
                businessWorkCurrent: '暂无业务',
                businessWork: [],
                viewId: '',
                statusUpdateTimer: null,
                businessInformation: [],
            }
        },
        methods: {
            // 获取当前拓扑图中所有已关联主机的未处理告警信息,生成告警信息表
            getCurrentTopologyAlertInfor() {
                // 获取所有节点hostid信息(若有)
                let hostids = []
                for (let i = 0; i < this.elementInf.selements.length; i++) {
                    if (this.elementInf.selements[i].elements.length !== 0) {
                        hostids.push(this.elementInf.selements[i].elements[0].hostid)
                    }
                }

                // 发送请求，获取数据
                axios.post("problem/getCurrentUnhandledProblemByHostids.action", {
                    hostids: hostids
                }).then((res) => {
                    // console.log(res);
                    if (res.data.content.result != null && res.data.content.result.length != 0) {
                        this.alertInformationlist = res.data.content.result
                        // 刷新当前告警状态
                        this.addWarningInf();
                    }
                }).catch((err) => {
                    this.$message.error("告警数据请求异常！")
                    console.log(err);
                })
            },

            // 单设备视图-获得某个主机的各项指标信息
            getHostRunInformation(e) {
                // 获取当前主机hostid(如果有的话)
                let flag = true
                this.businessInformation = []
                for (let i = 0; i < this.elementInf.selements.length; i++) {
                    if (e.target.text === this.elementInf.selements[i].label && this.elementInf.selements[i].elements.length !== 0) {
                        // console.log(this.elementInf.selements[i]);
                        // 请求数据并完成赋值
                        this.$axios.all(
                            [
                                this.$axios({
                                    method: 'post',
                                    url: 'host/getHostRunDetailsByHostid.action',
                                    data: {
                                        hostid: this.elementInf.selements[i].elements[0].hostid
                                    }
                                }),
                                this.$axios({
                                    method: 'post',
                                    url: '/business/get_business_by_hostId.action',
                                    params: {
                                        hostId: this.elementInf.selements[i].elements[0].hostid
                                    }
                                })
                            ]).then(this.$axios.spread((res1, res2) => {
                            // console.log(res);
                            if (res1 != null) {
                                let data = res1.data.content.result;
                                // console.log(data.host_base_inf)
                                this.hostAboutInformation.host_id = data.host_base_inf.hostid;
                                this.hostAboutInformation.host = data.host_base_inf.host;
                                this.hostAboutInformation.ip = data.host_base_inf.interfaces[0].ip;
                                this.hostAboutInformation.port = data.host_base_inf.interfaces[0].port;
                                this.hostAboutInformation.memery_utilization = parseFloat(data.memery_utilization).toFixed(2);
                                this.hostAboutInformation.DiskUtilization = parseFloat(data.DiskUtilization).toFixed(2);
                                this.hostAboutInformation.cpu_utilization = parseFloat(data.cpu_utilization).toFixed(2);
                                if (data.host_base_inf.snmp_available == '1' || data.host_base_inf.available == '1') {
                                    this.hostAboutInformation.status = "正常"
                                } else {
                                    this.hostAboutInformation.status = "异常"
                                }
                                if (data.host_base_inf.available == '0') {// 网络设备
                                    this.hostAboutInformation.type = '1'
                                } else if (data.host_base_inf.snmp_available == '0') {// 服务器
                                    this.hostAboutInformation.type = '0'
                                }
                            }
                            if (res2) {
                                // console.log(res2.data.content.result)
                                this.businessInformation = res2.data.content.result
                            }
                        }))
                            .catch((err) => {
                                console.log(err);
                            })
                        flag = false
                        break
                    }
                }
                if (flag) {
                    this.hostAboutInformation.host = e.target.text;
                    this.hostAboutInformation.ip = "--";
                    this.hostAboutInformation.port = "--";
                    this.hostAboutInformation.memery_utilization = "--";
                    this.hostAboutInformation.DiskUtilization = "--";
                    this.hostAboutInformation.cpu_utilization = "--";
                    this.hostAboutInformation.status = "--"
                }
            },

            // 告警定时器动画添加
            addWarningInf() {
                // 未关联主机的节点、以及未处理告警条数为0的节点不添加告警显示
                if (this.scene.getDisplayedElements().length !== 0) {
                    let nodeList = []
                    this.scene.getDisplayedElements().forEach((element) => {
                        if (element instanceof JTopo.Node) {
                            for (let i = 0; i < this.elementInf.selements.length; i++) {
                                // 在节点信息表中找到该节点，并且其hostid不为空
                                if (element.text === this.elementInf.selements[i].label && this.elementInf.selements[i].elements.length !== 0) {
                                    for (let j = 0; j < this.alertInformationlist.length; j++) {
                                        // 根据hostid在告警信息表中，找到对应信息，并且未处理告警总数不为0
                                        if (this.alertInformationlist[j].hostid === this.elementInf.selements[i].elements[0].hostid && this.alertInformationlist[j].alert_count !== 0) {
                                            nodeList.push(element)
                                            break;
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                    })

                    // 为筛选出的节点添加告警提示
                    if (nodeList.length !== 0) {
                        for (let i = 0; i < nodeList.length; i++) {
                            this.addWarning(nodeList[i])
                        }
                    }
                }
            },

            // 添加提示,node: 节点对象,text: 提示信息,color: 提示颜色
            addWarning(node, text, color) {
                node.alarmColor = color;
                let timer = setInterval(() => {
                    if (node.alarm === '存在未处理告警') {
                        node.alarm = null;
                    } else {
                        node.alarm = '存在未处理告警';
                        node.alarmAlpha = 0.9;
                    }
                }, 1500)
                // 保存定时器
                this.timerWarningList.push(timer)
            },

            // 视图切换
            viewSwitch(val) {
                // console.log(this.radioViewChoose);
                if (val === 2) {// 告警视图
                    this.viewFlag = true

                    // 清空已有的定时器
                    if (this.timerWarningList.length !== 0) {
                        this.timerWarningList.forEach((timer) => {
                            clearInterval(timer)
                        })
                    }

                    // 根据当前视图选择重新绘制拓扑图
                    this.getAllTuopu()
                } else if (val === 1) {// 运行视图
                    this.viewFlag = true

                    // 清空已有的告警定时器
                    if (this.timerWarningList.length !== 0) {
                        this.timerWarningList.forEach((timer) => {
                            clearInterval(timer)
                        })
                    }

                    // 清空所有节点的告警信息
                    if (this.scene.getDisplayedElements().length !== 0) {
                        let nodeList = []
                        this.scene.getDisplayedElements().forEach((element) => {
                            if (element instanceof JTopo.Node) {
                                nodeList.push(element)
                            }
                        })
                        if (nodeList.length !== 0) {
                            for (let i = 0; i < nodeList.length; i++) {
                                nodeList[i].alarm = null;
                            }
                        }
                    }

                    // 根据当前视图选择重新绘制拓扑图
                    this.getAllTuopu()
                } else if (val === 3) {// 业务视图
                    this.viewFlag = false
                    //清空画布
                    this.deleteElements(this.scene.getDisplayedElements())
                    //获取所有业务
                    this.getAllBusiness()
                }
            },

            // 添加运行状态表示，每隔10秒对状态进行刷新
            runStatusGet() {
                // 获取所有节点hostid信息(若有)
                let hostids = []
                let hostRunStatusList = []
                for (let i = 0; i < this.elementInf.selements.length; i++) {
                    if (this.elementInf.selements[i].elements.length !== 0) {
                        hostids.push(this.elementInf.selements[i].elements[0].hostid)
                    }
                }
                // console.log(hostids);
                // 请求,获取主机运行信息
                axios.post('host/getHostStatusByHostid.action', {
                    hostids: hostids
                }).then((res) => {
                    // console.log(res.data.content.result);
                    if (res.data.content.result != null && res.data.content.result.length != 0) {
                        hostRunStatusList = res.data.content.result;

                        // 运行状态更新至当前节点
                        this.scene.getDisplayedElements().forEach((element) => {
                            if (element instanceof JTopo.Node) {
                                for (let i = 0; i < this.elementInf.selements.length; i++) {
                                    // 在节点信息表中找到该节点，并且其hostid不为空
                                    if (element.text === this.elementInf.selements[i].label && this.elementInf.selements[i].elements.length !== 0) {
                                        for (let j = 0; j < hostRunStatusList.length; j++) {
                                            // 若节点已关联设备,并且监控状态正常,设置高亮,
                                            if (this.elementInf.selements[i].elements[0].hostid === hostRunStatusList[j].hostid) {
                                                if (hostRunStatusList[j].available === '1' || hostRunStatusList[j].snmp_available === '1') {
                                                    element.alpha = 1
                                                }
                                                break
                                            }
                                        }
                                        break;
                                    }
                                }
                            }
                        })
                        // 根据节点实际状态,设置其显示动画
                        this.scene.getDisplayedElements().forEach((element) => {
                            if (element instanceof JTopo.Link) {
                                if (element.nodeA.alpha !== 0.5 && element.nodeZ.alpha !== 0.5) {
                                    // 给连线添加单项数据流动画
                                    this.addAnimationToLink(element)
                                } else {
                                    element.strokeColor = '230,230,230'
                                }
                            }
                        })
                    }
                }).catch((err) => {
                    this.$message.error("运行状态信息请求出错！")
                    console.log(err);
                })
            },

            selectChanged(val) {
                // 重置告警信息表
                this.alertInformationlist = []
                // 重置节点信息表
                this.elementInf = []

                this.paintTopoMapBySysmapids(val.sysmapid)
                this.tuopuOptionsCurrent = val.name
            },

            // 获取所有拓扑图
            getAllTuopu() {
                axios.get('map/getAllMap.action').then((res) => {
                    // console.log(res);
                    if (res.data.content.result != null && res.data.content.result.length != 0) {
                        let tuopuAllInfor = res.data.content.result
                        this.tuopuOptions = []
                        tuopuAllInfor.forEach((item) => {
                            this.tuopuOptions.push({"name": item.name, "sysmapid": item.sysmapid})
                        })
                        // 每次刷新重新绘制为"当前选中的拓扑图"
                        if (this.tuopuOptionsCurrent == "无可展示拓扑图") {
                            this.tuopuOptionsCurrent = this.tuopuOptions[0].name
                            // 展示拓扑图
                            this.paintTopoMapBySysmapids(this.tuopuOptions[0].sysmapid)
                        } else {
                            // console.log(this.tuopuOptionsCurrent);
                            for (let i = 0; i < this.tuopuOptions.length; i++) {
                                if (this.tuopuOptions[i].name == this.tuopuOptionsCurrent) {
                                    // 展示拓扑图
                                    this.paintTopoMapBySysmapids(this.tuopuOptions[i].sysmapid)
                                }
                            }
                        }
                    } else {
                        this.$message.warning("拓扑图返回为空！")
                    }
                }).catch(err => {
                    this.$message.error("数据请求出错!")
                    console.log(err);
                })
            },

            // 获取所有业务
            async getAllBusiness() {
                //重置节点信息表
                this.businessWork = [],
                    this.$axios({
                        method: 'post',
                        url: '/business/get_all_business.action'
                    }).then((res) => {
                        // console.log(res.data.content.result)
                        let workList = res.data.content.result
                        workList.forEach((item) => {
                            this.businessWork.push(
                                {
                                    "workId": item.id,
                                    "workName": item.name
                                }
                            )
                        })
                        // console.log(this.businessWork)
                        this.businessWorkCurrent = this.businessWork[0].workName
                        this.paintBusinessMap(this.businessWork[0])
                    }).catch((error) => {
                        console.log(error)
                    })
            },

            //业务选择
            selectChangeBusiness(val) {
                this.businessWorkCurrent = val.workName
                //
                this.paintBusinessMap(val)
            },

            //绘制业务视图
            async paintBusinessMap(val) {
                let mapBusinessParams = {}
                await axios.post('/business/get_business_info.action', {
                    id: val.workId
                }).then((res) => {
                    mapBusinessParams = res.data.content.result
                    // console.log(mapBusinessParams)
                })
                // 清空当前画布
                if (this.scene.getDisplayedElements().length !== 0) {
                    this.deleteElements(this.scene.getDisplayedElements())
                }
                // 控制网格显示
                this.isGridShow = true
                // 创建中心业务结点
                var rootNode = this.addNode(val.workName, null, val.workId, 5);
                rootNode.alpha = 1
                rootNode.setLocation(Math.round(this.canvasWidth * 0.4), Math.round(this.canvasHeight * 0.4));
                rootNode.layout = {type: 'circle', radius: 150};
                // 创建与业务关联主机节点并进行连线
                let Node = null
                let icon = "6"
                for (let i = 0; i < mapBusinessParams.length; i++) {
                    if (mapBusinessParams[i].type == '数据库') {
                        icon = "7"
                    }
                    Node = this.addNode(mapBusinessParams[i].name, null, mapBusinessParams[i].real_id, icon)
                    Node.alpha = 1
                    this.addLink(rootNode, Node)
                }
                JTopo.layout.layoutNode(this.scene, rootNode, true);
                if (this.scene.getDisplayedElements().length !== 0) {
                    this.stage.centerAndZoom();
                    this.scene.addEventListener('mouseup', (e) => {
                        if (e.target && e.target.layout) {
                            JTopo.layout.layoutNode(this.scene, e.target, true);
                        }
                    });
                }
            },


            // 根据拓扑图sysmapids获取拓扑图内容，并绘制拓扑图
            paintTopoMapBySysmapids(sysmapids) {
                this.viewId = sysmapids
                let mapParams = {}
                axios.get('map/getMapBySysmapids.action', {
                    params: {
                        sysmapids: sysmapids
                    }
                }).then((res) => {
                    // console.log(res);
                    if (res.data.content.result != null && res.data.content.result.length != 0) {
                        mapParams = res.data.content.result[0]
                        this.elementInf = mapParams // 保存相关信息以备它用

                        // 清空当前画布
                        if (this.scene.getDisplayedElements().length !== 0) {
                            this.deleteElements(this.scene.getDisplayedElements())
                        }

                        // 控制网格显示
                        this.elementInf.grid_show === "0" ? this.isGridShow = true : this.isGridShow = false;

                        // 创建节点并进行连线
                        let Node = null
                        let currentNodeList = []
                        for (let i = 0; i < mapParams.selements.length; i++) {
                            // 元素尺寸
                            let size = {"width": mapParams.selements[i].width, "height": mapParams.selements[i].height}

                            Node = this.addNode(mapParams.selements[i].label, null, mapParams.selements[i].selementid, mapParams.selements[i].iconid_off, size)
                            Node.setLocation(parseInt(mapParams.selements[i].x), parseInt(mapParams.selements[i].y))
                            currentNodeList.push(Node)
                        }

                        let nameList = []
                        let nodeList = []
                        let link = null
                        for (let i = 0; i < mapParams.links.length; i++) {
                            // 遍历索引看该节点是否存在，存在则获得其Node对象并连线
                            // 获取连线两端两个节点的名称
                            nameList = []
                            mapParams.selements.forEach((node) => {
                                if (node.selementid === mapParams.links[i].selementid1 || node.selementid === mapParams.links[i].selementid2) {
                                    nameList.push(node.label)
                                }
                                if (nameList.length === 2) {
                                    return 0
                                }
                            })
                            // 依据名称在当前拓扑中找到对应的两个节点
                            nodeList = []
                            currentNodeList.forEach((item) => {
                                if (item.text === nameList[0] || item.text === nameList[1]) {
                                    nodeList.push(item)
                                }
                                if (nodeList.length === 2) {
                                    return 0
                                }
                            })
                            // 进行连线
                            link = this.addLink(nodeList[0], nodeList[1])
                        }
                        if (this.radioViewChoose == 2) {// 添加告警视图
                            // 清空已有的告警定时器
                            if (this.timerWarningList.length !== 0) {
                                this.timerWarningList.forEach((timer) => {
                                    clearInterval(timer)
                                })
                            }
                            this.getCurrentTopologyAlertInfor()
                        }
                        this.runStatusGet() // 运行视图默认添加
                        // 默认居中设置
                        currentNodeList.length != 0?this.stage.centerAndZoom():1;
                    }
                }).catch(err => {
                    console.log(err);
                    this.$message.error("拓扑图信息请求出错！")
                })
            },

            addNode(text, color, selementid, icon, size) {
                let node = new JTopo.Node(text);

                // 设置元素尺寸
                // 对图标尺寸进行校验，若超过设定阈值，则重设为默认值
                if(size == undefined || parseInt(size.width) > 120 || parseInt(size.height) > 120){
                    node.setSize(Math.round(parseInt(this.canvasWidth) * 0.012) * 3, Math.round(parseInt(this.canvasWidth) * 0.012) * 3)
                } else node.setSize(parseInt(size.width), parseInt(size.height))

                if (icon !== null) {
                    switch (icon) {
                        case "1":
                            node.setImage(this.topoImgSrc.switch.path)
                            break;
                        case "6":
                            node.setImage(this.topoImgSrc.server.path)
                            break;
                        case "2":
                            node.setImage(this.topoImgSrc.firewall.path)
                            break;
                        case "4":
                            node.setImage(this.topoImgSrc.gatekeeper.path)
                            break;
                        case "3":
                            node.setImage(this.topoImgSrc.router.path)
                            break;
                        case "7":
                            node.setImage(this.topoImgSrc.dataBase.path)
                            break;
                        default:
                            node.setImage(this.topoImgSrc.cloud.path)
                    }
                }
                node.fontColor = '0,0,0'; // 文字颜色
                node.alpha = 0.5
                node.shadow = false // 显示阴影

                this.scene.add(node);
                // 绑定单机事件-单击查看单设备视图
                if (this.radioViewChoose != 3) {
                    node.dbclick((e) => {
                        this.singleView = true
                        this.getHostRunInformation(e)
                    });
                }
                // 鼠标移入事件
                node.mouseover((e) => {
                    if (this.radioViewChoose === 2) {// 告警视图
                        // let x,y = 0;
                        // (e.target.x - e.target.width * 2.5) < 0 ? x = 0 : x = (e.target.x - e.target.width * 2.5);
                        // (e.target.y + 148) > this.canvas.height ? y = (this.canvas.height - 200) : y = e.target.y;
                        //
                        // $(".node-warning-dialog").css({"top": (y/this.canvas.height)*100+"%", "left": (x/this.canvas.width)*100+"%"})

                        this.nodeWarningDialogVisable = true
                        this.dialogTitle = text

                        // 检索出当前节点告警信息并显示
                        for (let i = 0; i < this.elementInf.selements.length; i++) {
                            // 在节点信息表中找到该节点，并且其hostid不为空
                            if (text === this.elementInf.selements[i].label && this.elementInf.selements[i].elements.length !== 0) {
                                for (let j = 0; j < this.alertInformationlist.length; j++) {
                                    // 根据hostid在告警信息表中，找到对应信息，并且未处理告警总数不为0
                                    if (this.alertInformationlist[j].hostid === this.elementInf.selements[i].elements[0].hostid && this.alertInformationlist[j].alert_count !== 0) {
                                        this.alertInformation = this.alertInformationlist[j]
                                        break;
                                    }
                                }
                                break;
                            }
                        }

                    }
                });
                // 鼠标移出事件
                node.mouseout((e) => {// 告警视图
                    if (this.radioViewChoose === 2) {
                        this.nodeWarningDialogVisable = false
                        this.dialogTitle = '';
                        this.alertInformation = {
                            "hostid": "",
                            "alert_count": 0,
                            "undefine": 0,
                            "infor": 0,
                            "alert": 0,
                            "yibanyanzhong": 0,
                            "yanzhong": 0,
                            "zainan": 0
                        }
                    }
                });
                return node;
            },

            addLink(nodeA, nodeZ) {
                var link = new JTopo.Link(nodeA, nodeZ);
                link.direction = 'vertical'
                // link.strokeColor = '164,176,190'
                link.strokeColor = '181,214,251'
                link.lineWidth = 1.5;
                this.scene.add(link);
                return link;
            },

            // 删除元素
            deleteElements(Elements) {
                if (Elements !== null && Elements.length !== 0) {
                    for (let i = 0; i < Elements.length; i++) {
                        this.scene.remove(Elements[i])
                    }
                }
            },

            // 初始化操作
            init() {
                this.canvas = document.getElementById("canvas")
                this.canvas.height = $(".map_body").height()
                this.canvas.width = $(".map_body").width()

                this.stage = new JTopo.Stage(canvas);
                // this.stage.frames = 240;
                // this.stage.eagleEye.visible = true// 鹰眼显示
                this.scene = new JTopo.Scene(this.stage);
            },

            //切换事件
            change(index) {
                this.showNumber = index
                console.log(index)
            },

            //全屏按钮
            // toggleFullscreen () {
            //   if (!screenfull.isEnabled) {
            //     return false
            //   }
            //   screenfull.toggle()
            //   // screenfull.request()
            // },

            toggleFullscreen() {
                // let element = document.documentElement;//设置后就是我们平时的整个页面全屏效果
                let element = document.getElementById('mapBody');//设置后就是   id==mapBody 的容器全屏
                let _myCanvas = document.getElementById("canvas");
                _myCanvas.setAttribute("width", this.canvasWidth);
                _myCanvas.setAttribute("height", this.canvasHeight);
                if (this.fullscreen) {
                    if (document.exitFullScreen) {
                        document.exitFullScreen();
                    } else if (document.webkitCancelFullScreen) {
                        document.webkitCancelFullScreen();
                    } else if (document.mozCancelFullScreen) {
                        document.mozCancelFullScreen();
                    } else if (document.msExitFullscreen) {
                        document.msExitFullscreen();
                    }
                } else {
                    let myCanvas = document.getElementById("canvas");
                    myCanvas.setAttribute("width", document.body.clientWidth);
                    myCanvas.setAttribute("height", document.body.clientWidth);
                    if (element.requestFullscreen) {
                        element.requestFullscreen();
                    } else if (element.webkitRequestFullScreen) {
                        element.webkitRequestFullScreen();
                    } else if (element.mozRequestFullScreen) {
                        element.mozRequestFullScreen();
                    } else if (element.msRequestFullscreen) {
                        // IE11
                        element.msRequestFullscreen();
                    }
                }
                this.fullscreen = !this.fullscreen;
                console.log(this.fullscreen)
            },

            // 向CanvasRenderingContext2D对象原型添加方法，连线动画
            canvas2DPrototypeMethodAdd() {
                // let context = this.canvas.getContext("2d")
                CanvasRenderingContext2D.prototype.JtopoDrawPointPath = function (a, b, c, d, e, f) {
                    var animespeed = (new Date()) / 18;// 获取时间
                    var xs = c - a,
                        xy = d - b,
                        l = Math.floor(Math.sqrt(xs * xs + xy * xy)),// Math.floor(x)返回与x接近且小于x的整数
                        colorlength = 5,// 动点的长度大小
                        j = l;
                    let xl = xs / l,
                        yl = xy / l;
                    var colorpoint = animespeed % (l + colorlength) - colorlength;
                    for (var i = 0; i < j; i++) {
                        if (((i) > colorpoint) && ((i) < (colorpoint + colorlength))) {
                            this.beginPath();
                            this.strokeStyle = e;
                            this.moveTo(a + (i - 1) * xl, b + (i - 1) * yl);
                            this.lineTo(a + i * xl, b + i * yl);
                            this.stroke();
                        } else {
                            this.beginPath();
                            this.strokeStyle = f;
                            this.moveTo(a + (i - 1) * xl, b + (i - 1) * yl);
                            this.lineTo(a + i * xl, b + i * yl)
                            this.stroke();
                        }
                    }
                }
            },

            // 给连线添加动画
            addAnimationToLink(link) {
                // link.PointPathColor="rgb(209,204,192)";
                link.PointPathColor = "rgb(181,214,251)";
                link.lineWidth = 1.5;
                link.strokeColor = "32, 191, 107"; // 动点颜色
                // link.strokeColor="235, 59, 90"; // 动点颜色
                link.paintPath = function (a, b) {// this指代当前线Link对象
                    if (this.nodeA === this.nodeZ) return void this.paintLoop(a);
                    a.beginPath(),
                        a.moveTo(b[0].x, b[0].y);
                    for (var c = 1; c < b.length; c++) {
                        null == this.dashedPattern ? (
                            (null == this.PointPathColor ? a.lineTo(b[c].x, b[c].y) : a.JtopoDrawPointPath(b[c - 1].x, b[c - 1].y, b[c].x, b[c].y, a.strokeStyle, this.PointPathColor))
                        ) : a.JTopoDashedLineTo(b[c - 1].x, b[c - 1].y, b[c].x, b[c].y, this.dashedPattern)
                    }
                    ;
                    if (a.stroke(), a.closePath(), null != this.arrowsRadius) {
                        var d = b[b.length - 2],
                            e = b[b.length - 1];
                        this.paintArrow(a, d, e)
                    }
                }
                this.scene.add(link)
            },
            //处理各种页面跳转
            pageJump(url, data) {
                this.$router.push({path: url, query: data})
            },
            //跳转到监控设备详情页面
            monitorDetail() {
                this.pageJump('basicMonitoring', {'hostid': this.hostAboutInformation.host_id})
            },
            //跳转到未处理告警页面
            unhandleAlertDetail() {
                this.$router.push({
                    name: 'UnhandledAlert',
                    params: {
                        host: this.hostAboutInformation.host,
                        hostid: this.hostAboutInformation.host_id
                    }
                })
            },
          //判断浏览器是否处于全屏状态 （需要考虑兼容问题）
          checkFull() {
            let isFull = document.mozFullScreen ||
                document.fullScreen ||
                //谷歌浏览器及Webkit内核浏览器
                document.webkitIsFullScreen ||
                document.webkitRequestFullScreen ||
                document.mozRequestFullScreen ||
                document.msFullscreenEnabled
            if (isFull === undefined) {
              isFull = false
            }
            return isFull;
          },
        },

        beforeRouteLeave(to, from, next) {
            // 页面跳转之前清空定时器
            if (this.statusUpdateTimer != null) clearInterval(this.statusUpdateTimer)
            next()
        },
        created() {
          let that = this
          window.onresize = function() {
            if (!that.checkFull()) {
              // 退出全屏
              that.fullscreen = false
              this.canvas.height = $(".map_body").height()
              this.canvas.width = $(".map_body").width()
            }
          }
        },
        mounted() {
            this.init()
            this.engineRoomDetails = this.$route.query
            this.canvas2DPrototypeMethodAdd()

            // 页面刷新之后，重新设置画布宽高
            window.addEventListener('load', e => {
                this.canvas.height = $(".map_body").height()
                this.canvas.width = $(".map_body").width()
            })

            this.getAllTuopu()
            if (this.statusUpdateTimer != null) clearInterval(this.statusUpdateTimer)
            this.statusUpdateTimer = setInterval(() => {// 每隔10s刷新当前状态
                if (this.radioViewChoose != 3) {
                    this.getAllTuopu()
                }
            }, 10000)
        },
        watch: {
            //监听鼠标选项变化
            radioMode(newMode, oldMode) {
                this.stage.mode = newMode
            },
            filterText(val) {
                this.$refs.tree.filter(val);
            }
        },
    }
</script>
